package com.server.questionbank.snframe.service.QuestionBank.Impl;

import com.server.questionbank.snframe.domain.Course.TCourse;
import com.server.questionbank.snframe.domain.Homework.TExercises;
import com.server.questionbank.snframe.domain.QuestionBank.DTO.ExercisesDto;
import com.server.questionbank.snframe.domain.QuestionBank.Exercises;
import com.server.questionbank.snframe.domain.QuestionBank.Question;
import com.server.questionbank.snframe.domain.ResDTO.PageResult;
import com.server.questionbank.snframe.mapper.QuestionBank.CoursesMapper;
import com.server.questionbank.snframe.mapper.QuestionBank.ExercisesMapper;
import com.server.questionbank.snframe.mapper.QuestionBank.QuestionMapper;
import com.server.questionbank.snframe.service.CourseService.*;
import com.server.questionbank.snframe.service.QuestionBank.ExercisesService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigInteger;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ExercisesServiceImpl implements ExercisesService {

    @Autowired
    private TExerciseService tExerciseService;
    @Autowired
    private TQuestionService tQuestionService;
    @Autowired
    private TKnowledgeService tKnowledgeService;
    @Autowired
    private TCourseService tCourseService;
    @Autowired
    private TChapterService tChapterService;
    @Autowired
    private ExercisesMapper exercisesMapper;

    @Autowired
    private QuestionMapper questionMapper;

    @Autowired
    private CoursesMapper coursesMapper;

    /**
     * 查询关于题的相关信息
     * @param type
     * @param sort
     * @return
     */

    @Override
    public PageResult<TExercises> getQuestionBanList(String type, Map<String, String> sort) {
        String sortName = "exercises_id";
        String sortType = "ASC";
        if (sort != null && !sort.isEmpty()) {
            if (sort.containsKey("sort[sortName]") && !sort.get("sort[sortName]").isEmpty())
                sortName = sort.get("sort[sortName]");
            if(sort.containsKey("sort[sortType]") && !sort.get("sort[sortType]").isEmpty())
                sortType = sort.get("sort[sortType]");
        }
        PageResult<TExercises> exercisesPage;
          if (sort.get("type").toString().equalsIgnoreCase("course")) exercisesPage = tExerciseService.getAllCourseExercises(
                sortName, sortType,
                Long.valueOf(sort.get("currentPage")), Long.valueOf(sort.get("pageSize"))
        );
        else exercisesPage = tExerciseService.getAllCompetitionExercises(
                    sortName, sortType,
                    Long.valueOf(sort.get("currentPage")), Long.valueOf(sort.get("pageSize"))
            );

        exercisesPage.getList().forEach(tExercises -> {
            // 题目问题
            tExercises.setQuestions(tQuestionService.getQuestionByExercisesId(tExercises.getExercisesId()));
            // 题目知识点
            tExercises.setKnowledges(tKnowledgeService.getKnowledgeByExercisesId(tExercises.getExercisesId()));
            // 题目课程
            tExercises.setCourseInfo(tCourseService.getCourseById(tExercises.getCourseId()));
            // 题目章节
            tExercises.setChapterInfo(tChapterService.getChapterInfo(tExercises.getChapterId()));
        });

//        System.out.println("sortSql:" + sortSql);
        return exercisesPage;
    }


    /**
     * 查询具体的题
     *
     * @param exercisesId
     * @return
     */
    @Override
    public TExercises selectById(Long exercisesId) {
        TExercises tExercises = tExerciseService.getExercisesById(exercisesId);
        if (tExercises != null) {
            tExercises.setQuestions(tQuestionService.getQuestionByExercisesId(exercisesId));
            tExercises.setKnowledges(tKnowledgeService.getKnowledgeByExercisesId(exercisesId));
            tExercises.setCourseInfo(tCourseService.getCourseById(tExercises.getCourseId()));
            tExercises.setChapterInfo(tChapterService.getChapterInfo(tExercises.getCourseId()));
        }
        return tExercises;
    }

    /**
     * 手动组卷根据条件查询的题
     *
     * @param params
     * @return
     */

    @Override
    public PageResult<TExercises> searchQuestions(ExercisesDto params) {
        try {
            // 参数提取
            String title = params.getTitle();
            Integer difficulty = params.getDifficulty();
            Long courseId = params.getCourseId();
            String questionType = params.getQuestionType();

            // 1. 分页参数校验
            if (params.getPageNum() == null || params.getPageNum() <= 0) {
                params.setPageNum(1L);
            }
            if (params.getPageSize() <= 0) {
                params.setPageSize(10L); // 默认分页大小
            }

            // 2. 查询符合条件的 exercises 总数（用于分页）
            Long total = exercisesMapper.getSearchExercisesCount(title, difficulty, courseId);
            long totalPages = (total + params.getPageSize() - 1) / params.getPageSize();
            if (params.getPageNum() > totalPages) {
                params.setPageNum(totalPages);
            }

            // 3. 分页查询 exercises 列表
            List<TExercises> exercisesList = exercisesMapper.getSearchExercises(
                    title, difficulty, courseId,
                    (params.getPageNum() - 1) * params.getPageSize(),
                    params.getPageSize()
            );

            // 4. 批量查询关联的 questions（避免 N+1 问题）
            if (!exercisesList.isEmpty()) {
                // 提取所有 exercisesId
                List<Long> exercisesIds = exercisesList.stream()
                        .map(TExercises::getExercisesId)
                        .collect(Collectors.toList());

                // 批量查询 questionType 过滤的 questions（Map<exercisesId, List<Question>>）
                Map<Long, List<Question>> questionsMap = tQuestionService
                        .findByExercisesIdsAndType(exercisesIds, questionType)
                        .stream()
                        .collect(Collectors.groupingBy(Question::getExercisesId));

                // 将 questions 设置到对应的 exercises 中
                exercisesList.forEach(exercise -> {
                    List<Question> questions = questionsMap.get(exercise.getExercisesId());
                    exercise.setQuestions(questions != null ? questions : Collections.emptyList());
                });
            }

            return new PageResult<>(
                    exercisesList,
                    total,
                    params.getPageNum(),
                    params.getPageSize()
            );
        } catch (Exception e) {
            e.printStackTrace();
            return null; // 或抛出业务异常
        }
    }

    /**
     * 批量获取题目及问题
     */
    @Transactional(readOnly = true)  // 添加事务注解
    public List<Exercises> findBatchExercisesWithQuestions(Long[] exercisesIds) {
        try {
            if (exercisesIds == null || exercisesIds.length==0) {
                return Collections.emptyList();
            }
            return exercisesMapper.findExercisesByIdsWithQuestions(exercisesIds);

        } catch (Exception e) {
            return Collections.emptyList();
        }
    }

    private Long convertToLong(Object obj) {
        if (obj instanceof BigInteger) {
            return ((BigInteger) obj).longValue();
        } else if (obj instanceof Long) {
            return (Long) obj;
        }
        return null;
    }

    private String getStringValue(Map<String, Object> row, String key) {
        Object value = row.get(key);
        return value != null ? value.toString() : null;
    }

    private float getFloatValue(Map<String, Object> row, String key) {
        Object value = row.get(key);
        return value != null ? Float.parseFloat(value.toString()) : 0.0f;
    }


    private List<Question> searchByQuestionParams(ExercisesDto params) {
        String questionType = params.getQuestionType();
        return questionMapper.searchByQuestionParams(questionType);
    }

    private List<TCourse> searchByCourseIdParams(ExercisesDto params) {
        // 根据业务需要构建资源查询条件
        Long courseId = params.getCourseId();
        return coursesMapper.searchByCourseIdParams(courseId);
    }


}
